package commServer;

import java.io.*;
import java.net.*;
import java.text.DecimalFormat;

import database.ModelClass;
import logic.AfterDecryption;
import logic.AuthenticateUser;
import logic.BitcoinExchangeRate;
import logic.Deposit;
import logic.TransferBTC;
import logic.ReceiptMail;
import logic.WriteFile;

/**
 * @author Niels
 * 
 */
/**
 * @author Niels
 * 
 */

		// TCPSERVERPROXY handles in coming and outgoing data, uses it in our functions and en/decrypts it
public class TCPServerProxy {

	public static void main(String[] args) {

		try {
			int serverPort = 7896;
			ServerSocket serverSocket = new ServerSocket(serverPort);

			System.out
					.println("System core initialization complete. Welcome back Commander!\n\nServer awaiting incoming client requests..\n");

			while (true) {
				Socket clientSocket = serverSocket.accept();
				Connection c = new Connection(clientSocket);
			}
		} catch (IOException mew) {
			mew.printStackTrace();
		}
	}
}

class Connection extends Thread {
	DataInputStream dataIN;
	DataOutputStream dataOUT;
	Socket clientSocket;

	En_Decrypt decryption;
	BitcoinExchangeRate exch;
	AfterDecryption afterdecryption;
	Deposit deposit;
	TransferBTC transferToUser;
	ReceiptMail receiptmail;
	WriteFile writeFile;
	ModelClass mc;

	private AuthenticateUser authenticateuser;
	String isUserAuth;
	String isTransferComplete;
	String isTransferToUserCompleted;
	String isMailSent;
	String encrypteddata;
	double newBalanceBTC;
	double newBalanceDKK;

	public Connection(Socket aClientSocket) {
		try {
			clientSocket = aClientSocket;
			dataIN = new DataInputStream(clientSocket.getInputStream());
			dataOUT = new DataOutputStream(clientSocket.getOutputStream());
			this.start();
		} catch (IOException pidgeotto) {
			pidgeotto.printStackTrace();
		}
	}

	public void run() {
		try {
			String data = dataIN.readUTF();
			System.out
					.print("Step 3. Server receives input from TCPClientProxy: "
							+ data);
			DecimalFormat df = new DecimalFormat("#.##");
			decryption = new En_Decrypt();
			String decrypteddata = decryption.xor_decrypt(data); // Decryption
																	// dekrypterer
																	// modtager
																	// String
			System.out
					.println("Step 4. Server decrypts message. Sends to AfterEncryption: "
							+ decrypteddata);

			afterdecryption = new AfterDecryption(decrypteddata); // AfterEncryption
																	// giver
																	// AUTH
																	// eller
																	// TRANSFER

			if (afterdecryption.getType().equals("AUTH")) {

				authenticateuser = new AuthenticateUser(
						afterdecryption.getUserEmail(),
						afterdecryption.getUserPass());
				mc = authenticateuser.getModelClass(); // Static mc bliver
														// lavet, således at
														// Transfer kan bruge
														// den senere
				isUserAuth = authenticateuser.getAuth();

				System.out
						.println("Step 6. AfterDecryption creates 2 strings - email and pass. "
								+ "These are used by AuthenticateUser to generate yes/no: "
								+ isUserAuth);

				encrypteddata = new String(decryption.xor_encrypt(isUserAuth));
				System.out.println("Step 7. yes/no is encrypted and sent: "
						+ encrypteddata);

			} else if (afterdecryption.getType().equals("TRANSFER")) {

				authenticateuser = new AuthenticateUser(
						afterdecryption.getUserEmail(),
						afterdecryption.getUserPass());
				mc = authenticateuser.getModelClass();

				deposit = new Deposit(afterdecryption.getTransferAmount(), mc
						.getCurrentUser().getEmail(), mc.getCurrentAccount()
						.getBitcoinBalance(), mc.getCurrentAccount()
						.getUserId());
				isTransferComplete = deposit.getIfConfirmed();
				newBalanceBTC = mc.getCurrentAccount().getBitcoinBalance()
						+ afterdecryption.getTransferAmount();
				mc.getCurrentAccount().setBitcoinBalance(newBalanceBTC);
				newBalanceDKK = newBalanceBTC * exch.btcRate() * 10;

				System.err.println("THIS IS NEW BALANCE: "
						+ df.format(newBalanceBTC));

				encrypteddata = new String(
						decryption.xor_encrypt(isTransferComplete + ":"
								+ df.format(newBalanceBTC) + ":"
								+ df.format(newBalanceDKK)));

			} else if (afterdecryption.getType().equals("TRANSFERTOUSER")) {

				authenticateuser = new AuthenticateUser(
						afterdecryption.getUserEmail(),
						afterdecryption.getUserPass());
				mc = authenticateuser.getModelClass();

				transferToUser = new TransferBTC(
						afterdecryption.getTransferAmount(), mc
								.getCurrentUser().getEmail(), mc
								.getCurrentAccount().getBitcoinBalance(), mc
								.getCurrentAccount().getUserId(),
						afterdecryption.getMailToUser());
				isTransferToUserCompleted = transferToUser
						.getIfTransferCompleted();
				newBalanceBTC = mc.getCurrentAccount().getBitcoinBalance()
						- afterdecryption.getTransferAmount();
				mc.getCurrentAccount().setBitcoinBalance(newBalanceBTC);
				newBalanceDKK = newBalanceBTC * exch.btcRate() * 10;

				encrypteddata = new String(
						decryption.xor_encrypt(isTransferToUserCompleted + ":"
								+ df.format(newBalanceBTC) + ":"
								+ df.format(newBalanceDKK)));

			} else if (afterdecryption.getType().equals("RECEIPT")) {

				authenticateuser = new AuthenticateUser(
						afterdecryption.getUserEmail(),
						afterdecryption.getUserPass());
				mc = authenticateuser.getModelClass();

				writeFile = new WriteFile(mc.getCurrentUser().getEmail(),
						afterdecryption.getReceiptDateTimeTxt(),
						afterdecryption.getReceiptDateTime(),
						afterdecryption.getReceiptAmount(),
						afterdecryption.getReceiptCopyright());
				System.out.println(afterdecryption.getReceiptDateTimeTxt());
				receiptmail = new ReceiptMail(mc.getCurrentUser().getEmail());

				isMailSent = receiptmail.getSent();

				encrypteddata = new String(decryption.xor_encrypt(isMailSent));
			}

			dataOUT.writeUTF(encrypteddata); // HER SENDER SERVEREN ET SVAR
												// TILBAGE TIL CLIENTEN
		} catch (IOException pidgeot) {
			pidgeot.printStackTrace();
		}
	}

}
